const express = require('express');
const router = express.Router();
const PriorityQueue = require('js-priority-queue');
const axios = require('axios');

const connection = require('./db.js'); // 确保 db.js 导出了正确的数据库配置

const getEdgesFromDatabase = (callback) => {
  const query = 'SELECT from_node, to_node, weight FROM edge';
  connection.query(query, (err, results, fields) => {
    if (err) {
      console.error('Error querying the database:', err);
      callback(err, null);
      return;
    }
    const edges = results.map(row => ({
      from: row.from_node,
      to: row.to_node,
      weight: parseInt(row.weight)
    }));
    callback(null, edges);
  });
};

const dijkstra = (graph, startNode) => {
  const distances = {};
  const previousNodes = {};
  const visited = {};
  const nodes = new PriorityQueue({
    comparator: (a, b) => a.distance - b.distance
  });

  for (let node in graph) {
    distances[node] = node === startNode ? 0 : Infinity;
    previousNodes[node] = null;
    nodes.queue({ node, distance: distances[node] });
  }

  while (nodes.length) {
    const { node, distance } = nodes.dequeue();
    if (visited[node]) continue;
    visited[node] = true;

    for (let edge of graph[node]) {
      const { to, weight } = edge;
      if (!visited[to]) {
        const newDistance = distance + weight;
        if (newDistance < distances[to]) {
          distances[to] = newDistance;
          previousNodes[to] = node;
          nodes.queue({ node: to, distance: newDistance });
        }
      }
    }
  }

  return { distances, previousNodes };
};

const getShortestPathWithCoordinates = (from_node, to_node, callback) => {
  getEdgesFromDatabase((err, edges) => {
    if (err) {
      callback(err, null);
      return;
    }

    const graph = {};
    edges.forEach(({ from, to, weight }) => {
      if (!graph[from]) graph[from] = [];
      graph[from].push({ to, weight });
      if (!graph[to]) graph[to] = [];
      graph[to].push({ to: from, weight });
    });

    const { distances, previousNodes } = dijkstra(graph, from_node);

    let path = [];
    let currentNode = to_node;
    while (currentNode !== null) {
      path.unshift(currentNode);
      currentNode = previousNodes[currentNode];
    }

    if (path[0] !== from_node) {
      callback(null, 'No path found');
      return;
    }

    // 获取路径上每个节点的坐标信息
    const getLocationInfo = (node) => {
      return axios.post('http://127.0.0.1:3000/api/loc/find', { spotname: node })
        .then(response => ({
          spotname:response.data.spotname,
          latitude: response.data.latitude,
          longitude: response.data.longitude
        }))
        .catch(error => {
          console.error('Error retrieving location info:', error);
          return null;
        });
    };

    Promise.all(path.map(getLocationInfo))
      .then(locations => {
        callback(null, locations);
      })
      .catch(err => {
        callback(err, null);
      });
  });
};

router.post('/shortest-path', (req, res) => {
  const { from_node, to_node } = req.body;

  if (!from_node || !to_node) {
    return res.status(400).json({ error: 'Missing from_node or to_node' });
  }

  getShortestPathWithCoordinates(from_node, to_node, (err, path) => {
    if (err) {
      console.error(err);
      return res.status(500).json({ error: 'Internal server error' });
    }
    res.json({ path });
  });
});

module.exports = router;